package com.neuronrobotics.aim.gui;

//import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.border.CompoundBorder;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

public class EventResponseTable extends JTable {

	private static final long serialVersionUID = 1L;

	public boolean isDouble(String string) {
		try {
			Double.parseDouble(string);
		} catch (NumberFormatException e) {
			System.out.println(string + " isn't a number");
			return false;
		}
		//System.out.println("The " + string + " is a number");
		return true;
	}

	/**
	 * This constructor initializes table elements	
	 * 	
	 * @param tableElements size 4x4 array	
	 * @param bounds: 4x1 vector
	 */
	public EventResponseTable(double[][] tableElements, int[] bounds) {
		this.setBorder(new CompoundBorder());
		this.setModel(new DefaultTableModel(new Object[][] {
				{ tableElements[0][0], tableElements[0][1],
						tableElements[0][2], tableElements[0][3] },
				{ tableElements[1][0], tableElements[1][1],
						tableElements[1][2], tableElements[1][3] },
				{ tableElements[2][0], tableElements[2][1],
						tableElements[2][2], tableElements[2][3] },
				{ tableElements[3][0], tableElements[3][1],
						tableElements[3][2], tableElements[3][3] }, },
				new String[] { "t", "s", "n", "Position" }) {
			private static final long serialVersionUID = -2115861646443740429L;
			@SuppressWarnings("rawtypes")
			Class[] columnTypes = new Class[] { Double.class, Double.class,
					Double.class, Double.class };

			@SuppressWarnings({ "unchecked", "rawtypes" })
			public Class getColumnClass(int columnIndex) {
				return columnTypes[columnIndex];
			}
		});

		this.getColumnModel().getColumn(0).setResizable(false);
		this.getColumnModel().getColumn(0).setMaxWidth(100);
		this.getColumnModel().getColumn(1).setResizable(false);
		this.getColumnModel().getColumn(2).setResizable(false);
		this.getColumnModel().getColumn(3).setResizable(false);
		this.getColumnModel().getColumn(3).setMaxWidth(100);
		// this.setBounds(10, 94, 200, 62);
		this.setBounds(bounds[0], bounds[1], bounds[2], bounds[3]);
		// begin table event listener
		this.getModel().addTableModelListener(new TableModelListener() {
			public void tableChanged(TableModelEvent e) {

				int row = e.getFirstRow();
				int column = e.getColumn();
				TableModel model = (TableModel) e.getSource();
				Object data = model.getValueAt(row, column);
				String dataString = data.toString();

				boolean isDouble = isDouble(dataString);
				if (isDouble == false) {
					String message = "\"The table element must be numbers\"\n";
					JOptionPane.showMessageDialog(new JFrame(), message,
							"Dialog", JOptionPane.YES_NO_OPTION);
				} else {
				//	double aDouble = Double.parseDouble(dataString);
				//	System.out.println("Column " + "  Row " + "  " + aDouble);					
				}
			}
		});
		// end of table event listener
	}

	public double[][] getTableData() {
		// DefaultTableModel model = (DefaultTableModel) this.getModel();
		// Vector data= model.getDataVector();
		int columnNumber = this.getModel().getColumnCount();
		int rowNumber = this.getModel().getRowCount();
		double[][] data = new double[rowNumber][columnNumber];

		for (int i = 0; i < rowNumber; i++) {
			for (int j = 0; j < columnNumber; j++) {
				data[i][j] = (Double) this.getModel().getValueAt(i, j);
			}
		}
		return data;
	}
	
	public void setTableData(double[][] rotationMatrix, double[] posVector) {
		
		if ((rotationMatrix.length!=3)|(rotationMatrix[0].length!=3)|(posVector.length!=3))
		{
			System.err.println("Rotation matrix or Position vector has wrong dimension");
		}
		else{			
			//setValueAt(value,row,column);
			this.getModel().setValueAt(rotationMatrix[0][0],0,0);
			this.getModel().setValueAt(rotationMatrix[1][0],0,1);
			this.getModel().setValueAt(rotationMatrix[2][0],0,2);
			this.getModel().setValueAt(posVector[0],0,3);

			this.getModel().setValueAt(rotationMatrix[0][1],1,0);
			this.getModel().setValueAt(rotationMatrix[1][1],1,1);
			this.getModel().setValueAt(rotationMatrix[2][1],1,2);
			this.getModel().setValueAt(posVector[1],1,3);
			
			this.getModel().setValueAt(rotationMatrix[0][2],2,0);
			this.getModel().setValueAt(rotationMatrix[1][2],2,1);
			this.getModel().setValueAt(rotationMatrix[2][2],2,2);
			this.getModel().setValueAt(posVector[2],2,3);			
		}
	}
	
	/**
	 * Get table element
	 * 	
	 * @param row index
	 * @param column index
	 */
	public double getTableElement(int row, int column) {
		return (Double) this.getModel().getValueAt(row, column);
	}

	/**
	 * set table element
	 * 	
	 * @param element value
	 * @param row index
	 * @param column index
	 */
	public void setTableElement(double value, int row, int column) {
		  this.getModel().setValueAt(value,row,column);
	}
	
	public void printDoubleDataArray() {
		for (int i = 0; i < this.getTableData().length; i++) {
			for (int j = 0; j < this.getTableData()[0].length; j++) {
				System.out.print(this.getTableData()[i][j] + " ");
			}
			System.out.println("\n");
		}
	}

}
